const express = require('express');
const multer = require('multer');
const router = express.Router();

// 导入工具和中间件
const { success, error, badRequest, notFound, forbidden, asyncHandler, paginated } = require('../utils/response');
const { authenticateToken } = require('../utils/auth');
const { validatePagination, validateFileType, validateFileSize, validateEnum } = require('../utils/validation');

// 导入服务层和DAO层
const gameService = require('../services/gameService');
const gameDao = require('../dao/gameDao');

// 配置文件上传
const storage = multer.memoryStorage();
const upload = multer({
  storage: storage,
  limits: {
    fileSize: 10 * 1024 * 1024, // 10MB
    files: 1
  },
  fileFilter: (req, file, cb) => {
    const allowedTypes = ['mp3', 'wav', 'm4a'];
    const validation = validateFileType(file, allowedTypes);
    if (validation.isValid) {
      cb(null, true);
    } else {
      cb(new Error(validation.message), false);
    }
  }
});

/**
 * 获取游戏内容
 * GET /game/contents
 */
router.get('/contents', asyncHandler(async (req, res) => {
  const { level, category, count = 10 } = req.query;
  
  // 验证难度参数
  if (level) {
    const levelValidation = validateEnum(level, ['easy', 'medium', 'hard'], '难度级别');
    if (!levelValidation.isValid) {
      return badRequest(res, levelValidation.message);
    }
  }

  const options = {
    difficulty: level,
    category,
    limit: Math.min(parseInt(count) || 10, 50) // 最多50个
  };

  const contents = await gameDao.getRandomGameContents(options);

  const formattedContents = contents.map(content => ({
    id: content.id,
    image: content.image,
    pinyin: content.pinyin,
    standardText: content.standard_text,
    level: content.difficulty,
    category: content.category,
    audioUrl: content.audio_url,
    hints: content.hints ? JSON.parse(content.hints) : []
  }));

  success(res, formattedContents);
}));

/**
 * 获取单个游戏内容
 * GET /game/contents/:id
 */
router.get('/contents/:id', asyncHandler(async (req, res) => {
  const { id } = req.params;
  
  if (!id || isNaN(parseInt(id))) {
    return badRequest(res, '无效的游戏内容ID');
  }

  const content = await gameDao.getGameContentById(parseInt(id));
  
  if (!content) {
    return notFound(res, '游戏内容不存在');
  }

  const formattedContent = {
    id: content.id,
    image: content.image,
    pinyin: content.pinyin,
    standardText: content.standard_text,
    level: content.difficulty,
    category: content.category,
    audioUrl: content.audio_url,
    hints: content.hints ? JSON.parse(content.hints) : [],
    description: content.description
  };

  success(res, formattedContent);
}));

/**
 * 提交游戏结果
 * POST /game/submit
 */
router.post('/submit', authenticateToken, upload.single('audioFile'), asyncHandler(async (req, res) => {
  const { contentId, duration } = req.body;
  const audioFile = req.file;
  const userId = req.user.id;

  // 参数验证
  if (!contentId || isNaN(parseInt(contentId))) {
    return badRequest(res, '无效的游戏内容ID');
  }

  if (!audioFile) {
    return badRequest(res, '请上传音频文件');
  }

  if (!duration || isNaN(parseFloat(duration))) {
    return badRequest(res, '请提供录音时长');
  }

  // 验证文件大小
  const fileSizeValidation = validateFileSize(audioFile, 10 * 1024 * 1024); // 10MB
  if (!fileSizeValidation.isValid) {
    return badRequest(res, fileSizeValidation.message);
  }

  const contentIdInt = parseInt(contentId);
  const durationFloat = parseFloat(duration);

  // 检查游戏内容是否存在
  const gameContent = await gameDao.getGameContentById(contentIdInt);
  if (!gameContent) {
    return notFound(res, '游戏内容不存在');
  }

  // TODO: 这里应该调用语音识别和相似度计算服务
  // 现在使用模拟数据
  const mockResult = {
    userPronunciation: gameContent.pinyin, // 模拟识别结果
    similarity: Math.floor(Math.random() * 30) + 70, // 70-100%
    score: Math.floor(Math.random() * 30) + 70, // 70-100分
    suggestions: ['发音清晰，继续保持', '注意声调的准确性']
  };

  // 保存音频文件 (这里应该保存到文件系统或云存储)
  const audioUrl = `https://example.com/game/recordings/${Date.now()}_${audioFile.originalname}`;

  // 创建游戏记录
  const recordData = {
    user_id: userId,
    content_id: contentIdInt,
    user_pronunciation: mockResult.userPronunciation,
    similarity_score: mockResult.similarity,
    score: mockResult.score,
    audio_url: audioUrl,
    duration: durationFloat,
    suggestions: JSON.stringify(mockResult.suggestions)
  };

  const gameRecord = await gameDao.createGameRecord(recordData);

  // 确定评级
  let level = '需要改进';
  if (mockResult.score >= 90) {
    level = '优秀';
  } else if (mockResult.score >= 80) {
    level = '良好';
  } else if (mockResult.score >= 70) {
    level = '一般';
  }

  const responseData = {
    id: gameRecord.id,
    contentId: contentIdInt,
    userPronunciation: mockResult.userPronunciation,
    standardPronunciation: `${gameContent.standard_text} (${gameContent.pinyin})`,
    similarity: mockResult.similarity,
    score: mockResult.score,
    level,
    suggestions: mockResult.suggestions,
    createdAt: gameRecord.created_at
  };

  success(res, responseData, '游戏结果提交成功');
}));

/**
 * 获取游戏记录
 * GET /game/records
 */
router.get('/records', authenticateToken, asyncHandler(async (req, res) => {
  const { page, limit } = validatePagination(req.query);
  const userId = req.user.id;

  const result = await gameDao.getUserGameRecords(userId, { page, limit });

  const formattedList = result.records.map(record => {
    let level = '需要改进';
    if (record.score >= 90) {
      level = '优秀';
    } else if (record.score >= 80) {
      level = '良好';
    } else if (record.score >= 70) {
      level = '一般';
    }

    return {
      id: record.id,
      contentTitle: record.gameContent ? record.gameContent.standard_text : '未知内容',
      contentImage: record.gameContent ? record.gameContent.image : null,
      score: record.score,
      level,
      similarity: record.similarity_score,
      createdAt: record.created_at,
      duration: record.duration
    };
  });

  // 获取统计数据
  const statistics = await gameDao.getUserGameStats(userId);

  paginated(res, formattedList, result.total, page, limit, { statistics });
}));

/**
 * 获取游戏记录详情
 * GET /game/records/:id
 */
router.get('/records/:id', authenticateToken, asyncHandler(async (req, res) => {
  const { id } = req.params;
  const userId = req.user.id;
  
  if (!id || isNaN(parseInt(id))) {
    return badRequest(res, '无效的游戏记录ID');
  }

  const record = await gameDao.getGameRecordById(parseInt(id));
  
  if (!record) {
    return notFound(res, '游戏记录不存在');
  }

  // 检查是否为当前用户的记录
  if (record.user_id !== userId) {
    return forbidden(res, '无权访问此游戏记录');
  }

  let level = '需要改进';
  if (record.score >= 90) {
    level = '优秀';
  } else if (record.score >= 80) {
    level = '良好';
  } else if (record.score >= 70) {
    level = '一般';
  }

  const detailData = {
    id: record.id,
    contentTitle: record.gameContent ? record.gameContent.standard_text : '未知内容',
    contentImage: record.gameContent ? record.gameContent.image : null,
    contentPinyin: record.gameContent ? record.gameContent.pinyin : '',
    userPronunciation: record.user_pronunciation,
    standardPronunciation: record.gameContent ? `${record.gameContent.standard_text} (${record.gameContent.pinyin})` : '',
    score: record.score,
    level,
    similarity: record.similarity_score,
    duration: record.duration,
    audioUrl: record.audio_url,
    suggestions: record.suggestions ? JSON.parse(record.suggestions) : [],
    createdAt: record.created_at
  };

  success(res, detailData);
}));

/**
 * 获取游戏排行榜
 * GET /game/leaderboard
 */
router.get('/leaderboard', asyncHandler(async (req, res) => {
  const { period = 'all', limit = 10 } = req.query;
  
  // 验证周期参数
  const periodValidation = validateEnum(period, ['week', 'month', 'all'], '统计周期');
  if (!periodValidation.isValid) {
    return badRequest(res, periodValidation.message);
  }

  const leaderboard = await gameDao.getGameLeaderboard({
    period,
    limit: parseInt(limit)
  });

  const formattedLeaderboard = leaderboard.map((item, index) => ({
    rank: index + 1,
    userId: item.user_id,
    username: item.user.username,
    nickname: item.user.nickname,
    avatar: item.user.avatar,
    averageScore: parseFloat(item.dataValues.avgScore).toFixed(1),
    gameCount: parseInt(item.dataValues.gameCount),
    bestScore: parseInt(item.dataValues.bestScore || 0)
  }));

  success(res, formattedLeaderboard);
}));

/**
 * 获取游戏分类
 * GET /game/categories
 */
router.get('/categories', asyncHandler(async (req, res) => {
  const categories = await gameDao.getGameCategories();
  
  const formattedCategories = categories.map(category => ({
    key: category,
    name: getCategoryName(category),
    icon: getCategoryIcon(category)
  }));

  success(res, formattedCategories);
}));

/**
 * 获取今日挑战
 * GET /game/daily-challenge
 */
router.get('/daily-challenge', asyncHandler(async (req, res) => {
  // 获取今日挑战内容（可以基于日期生成固定的挑战）
  const today = new Date().toISOString().split('T')[0];
  const seed = today.split('-').join(''); // 使用日期作为种子
  
  const challenge = await gameDao.getDailyChallengeContent(seed);
  
  if (!challenge) {
    return notFound(res, '今日挑战内容不存在');
  }

  const formattedChallenge = {
    id: challenge.id,
    date: today,
    image: challenge.image,
    pinyin: challenge.pinyin,
    standardText: challenge.standard_text,
    level: challenge.difficulty,
    category: challenge.category,
    audioUrl: challenge.audio_url,
    description: '今日挑战：' + (challenge.description || challenge.standard_text),
    hints: challenge.hints ? JSON.parse(challenge.hints) : []
  };

  success(res, formattedChallenge);
}));

// 辅助函数：获取分类名称
function getCategoryName(category) {
  const categoryNames = {
    'fruit': '水果',
    'animal': '动物',
    'color': '颜色',
    'number': '数字',
    'daily': '日常用品',
    'food': '食物',
    'nature': '自然',
    'body': '身体部位'
  };
  return categoryNames[category] || category;
}

// 辅助函数：获取分类图标
function getCategoryIcon(category) {
  const categoryIcons = {
    'fruit': '🍎',
    'animal': '🐱',
    'color': '🎨',
    'number': '🔢',
    'daily': '🏠',
    'food': '🍜',
    'nature': '🌳',
    'body': '👤'
  };
  return categoryIcons[category] || '📝';
}

module.exports = router;
